<?php

namespace App\Trip\Plane\Requests;

use App\Models\Plane\Airports\Repositories\Interfaces\AirportRepositoryInterface;
use App\Models\Plane\Cities\Repositories\Interfaces\PlaneCityRepositoryInterface;
use Exception;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Support\Arrayable;

class AirportRequest implements Arrayable
{
    private array $airport;
    /**
     * @var AirportRepositoryInterface|(AirportRepositoryInterface&Application)|Application|mixed
     */
    private mixed $airportRepo;
    /**
     * @var PlaneCityRepositoryInterface|(PlaneCityRepositoryInterface&Application)|Application|mixed
     */
    private mixed $planeCitiesRepo;

    public function __construct(array $airport)
    {
        $this->airport         = $airport;
        $this->airportRepo     = app(AirportRepositoryInterface::class);
        $this->planeCitiesRepo = app(PlaneCityRepositoryInterface::class);
    }

    /**
     * @throws Exception
     */
    public function __invoke(string $field = '')
    {
        if (!$field) {
            return $this->airport;
        }

        if (isset($this->airport[$field])) {
            return $this->airport[$field];
        }

        throw new Exception('没有意义');
    }

    /**
     * @throws Exception
     */
    public function getCityName()
    {
        // $input
        $city_name = $this->airport['city_name'] ?? '';
        if (!$city_name) {
            // 从code 获取
            if (0 == $this->getType()) {
                $city_code = $this->getCityCode();
                $city_name = $this->planeCitiesRepo->findOneByCode($city_code)?->getName();
            } elseif (2 == $this->getType()) {
                $city_code = $this->airportRepo->findOneByCode($this->getCode())?->getPlaneCityCode();
                $city_name = $city_code ? $this->planeCitiesRepo->findOneByCode($city_code)?->getName() : '';
            }
        }

        if (!$city_name) {
            throw new Exception("city param error ");
        }

        return $city_name;
    }

    public function getType()
    {
        return $this->airport['type'];
    }

    /**
     * @throws Exception
     */
    public function getCityCode(): string
    {
        // 如果type 是城市 且 code 为数字
        if (0 == $this->getType()) {
            $planeCityRepo = app(PlaneCityRepositoryInterface::class);
            if (is_numeric($this->getCode())) {
                $city = $planeCityRepo->findOneByAdCode($this->getCode());
            } else {
                // 机场城市三字码
                $city = $planeCityRepo->findOneByCode($this->getCode());
            }
            return $city?->getCode() ?: '';
        } else if (2 == $this->getType()) {
            $airRepo = app(AirportRepositoryInterface::class);
            $air     = $airRepo->findOneByCode($this->getCode());
            return $air->getPlaneCityCode();
        } else {
            throw new Exception("未匹配到相关城市");
        }
    }

    public function getCode()
    {
        return $this->airport['code'];
    }

    // 获取三字码

    /**
     * @throws Exception
     */
    public function getAirportCode()
    {
        // 如果type 是城市 且 code 为数字
        if (0 == $this->getType()) {
            $planeCityRepo = app(PlaneCityRepositoryInterface::class);
            $airportRepo   = app(AirportRepositoryInterface::class);
            if (is_numeric($this->getCode())) {
                $city = $planeCityRepo->findOneByAdCode($this->getCode());
            } else {
                // 机场城市三字码
                $city = $planeCityRepo->findOneByCode($this->getCode());
            }
            $airport_city_code = $city?->getCode() ?: '';
            if (!$airport_city_code) {
                throw new Exception("未匹配到相关城市");
            }
            $airport = $airportRepo->findOneByCityCode($airport_city_code);
            return $airport?->getCode() ?: "";
        } else {
            return $this->airport['code'];
        }
    }

    public function toArray(): array
    {
        return $this->airport;
    }
}